---
title: Authentication and authorization
summary: Authentication contributed by the base class, authorization enforcement, per-endpoint access requirements, and security findings.
status: draft
owner: Architecture
last_reviewed: 2026-10-09
---

# Authentication and authorization

Callers are identified by authentication services that the `CoreAPIStartup` base class registers; those services are not visible in this repository. Access to every endpoint is gated by a single resource requirement, `[SecurityApiAuthorize("DBConnAPIRetrieveResource")]`, applied at controller level on both controllers. There is no data-level authorization, so any caller granted the resource can retrieve credentials for any server, instance and user the Environment API holds.

## Authentication

| Aspect | Finding |
| --- | --- |
| Schemes registered | None in local source (no `AddAuthentication`, `AddJwtBearer` or `[Authorize(AuthenticationSchemes = value)]`). `DisableAuthServices` is not set, so authentication services are contributed by `CoreAPIStartup` (opaque) † |
| Scheme options | Not visible in this repository; scheme names and setting keys are read inside the base** |
| Identity type | `IIdentityServiceAccessor` (`SAIF.NetCore.ServiceExtensions`) — read for `UserId` and `AuthenticationScheme` in audit logging only |
| Pipeline position | Inside the opaque `base.Configure` call (see [Hosting pipeline](hosting-pipeline.md#middleware-pipeline)); package documentation lists `UseAuthentication()` there † |
| Anonymous access | Not determined from source**. The Swagger JSON and UI are registered before the opaque pipeline and are therefore served without authentication* |

Authentication is established entirely by the base class. The pipeline definition enables both IIS Windows and anonymous authentication, and `ConnectionsController` logs the authentication scheme of each caller, which suggests more than one scheme can authenticate callers*.

## Authorization enforcement

| Mechanism | Scope | Declared in | Effect |
| --- | --- | --- | --- |
| `[SecurityApiAuthorize("DBConnAPIRetrieveResource")]` | Controller | `DBConnectionAPI/DBConnectionAPI/Controllers/ConnectionsController.cs` | Caller must be authorized for the resource on all 3 retrieval endpoints |
| `[SecurityApiAuthorize("DBConnAPIRetrieveResource")]` | Controller | `DBConnectionAPI/DBConnectionAPI/Controllers/AdminController.cs` | Caller must be authorized for the same resource on all 3 Admin endpoints |
| Authorization policies | — | None defined (`AddAuthorization`, `ConfigureAuthorizationOptions` absent) | None in code |
| `[AllowAnonymous]` | — | None in code | No endpoint overrides the controller requirement |
| Programmatic check | — | None in code | No check inside any action or service |

Inherited behavior †: `SecurityApiAuthorize` is evaluated by the package's security handler, which requires a non-blank `User.Identity.Name`, strips a `DOMAIN\` prefix, splits the required roles on `,` and calls `ISecurityClient.IsAuthorized(user, role)` for each, succeeding on the first `true` ([BR-DBC-025](business-rules.md#br-dbc-025-resource-authorization-on-every-endpoint)). The status returned to a denied caller is not stated in package documentation**; 401 or 403 by ASP.NET Core convention*.

## Access requirements by endpoint

| Endpoint | Requirement | Enforced by | On failure |
| --- | --- | --- | --- |
| [`POST /v1/Admin/GetOracleConnectionInfo`](endpoints/admin.md#post-v1-admin-getoracleconnectioninfo) | `DBConnAPIRetrieveResource` | Controller-level `[SecurityApiAuthorize]` | `401`/`403`** |
| [`POST /v1/Admin/GetPostgresConnectionInfo`](endpoints/admin.md#post-v1-admin-getpostgresconnectioninfo) | `DBConnAPIRetrieveResource` | Controller-level `[SecurityApiAuthorize]` | `401`/`403`** |
| [`POST /v1/Admin/GetSqlConnectionInfo`](endpoints/admin.md#post-v1-admin-getsqlconnectioninfo) | `DBConnAPIRetrieveResource` | Controller-level `[SecurityApiAuthorize]` | `401`/`403`** |
| [`GET /v1/Connections/ORA/{instance}/{username}`](endpoints/connections.md#get-v1-connections-ora-instance-username) | `DBConnAPIRetrieveResource` | Controller-level `[SecurityApiAuthorize]` | `401`/`403`** |
| [`GET /v1/Connections/PostgreSQL/{instance}/{username}`](endpoints/connections.md#get-v1-connections-postgresql-instance-username) | `DBConnAPIRetrieveResource` | Controller-level `[SecurityApiAuthorize]` | `401`/`403`** |
| [`GET /v1/Connections/SQL/{server}/{instance}/{username}`](endpoints/connections.md#get-v1-connections-sql-server-instance-username) | `DBConnAPIRetrieveResource` | Controller-level `[SecurityApiAuthorize]` | `401`/`403`** |

The Swagger JSON and UI endpoints are not covered by any requirement in code (**None in code**).

## Roles and resources

| Role / resource | Grants | Used by | Source |
| --- | --- | --- | --- |
| `DBConnAPIRetrieveResource` | Access to all six endpoints, including those that return raw credentials; what the Security service maps to this resource is not visible in source** | All endpoints on [`ConnectionsController`](endpoints/connections.md) and [`AdminController`](endpoints/admin.md) | `DBConnectionAPI/DBConnectionAPI/Controllers/ConnectionsController.cs`; `DBConnectionAPI/DBConnectionAPI/Controllers/AdminController.cs` |

## Data-level authorization

**None in code.** No check ties the requesting identity to the `instance`, `server` or `username` being requested. Access is all-or-nothing on `DBConnAPIRetrieveResource`.

## Secrets handling

| Secret | Retrieved by | Consumed by | Notes |
| --- | --- | --- | --- |
| Per-user database credentials (secure-setting key patterns `ora_<instance>_<username>`, `sql_<server>_<instance>_<username>`, `postgres_<instance>_<username>`, lower-cased, group `dbconnectionapi`) | `IEnvironmentClient.GetSecureSetting<string>(key, "dbconnectionapi", ISystemHashService.Get(SystemType.WebApp))` | `ConnectionManager`, `AdminController` | Decrypted in memory, composed into a string and returned to the caller; composed strings are cached in clear text in process memory for the process lifetime ([BR-DBC-004](business-rules.md#br-dbc-004-cache-entries-never-expire)) |
| Secure environment client | `EnableSecureEnvironmentClient<Startup>()` in the `Startup` constructor (opaque) † | `CoreAPIStartup` | Registers the secure `IEnvironmentClient`; effect is not visible in source |

No secret value is held in `appsettings*.json`.

## Security rules

### SEC-API-001 Resource requirement on every endpoint

| Field | Value |
| --- | --- |
| **Statement** | A caller must be authorized for resource `DBConnAPIRetrieveResource` to reach any endpoint |
| **Trigger** | Every request routed to either controller |
| **Enforcement** | Controller-level `[SecurityApiAuthorize("DBConnAPIRetrieveResource")]`, evaluated by the package security handler † |
| **Applies to** | [`ConnectionsController`](endpoints/connections.md) and [`AdminController`](endpoints/admin.md) endpoints (see [Endpoints](endpoints.md)) |
| **Outcome** | Denied request: status not stated in package documentation** (401 or 403*) |
| **Source** | `DBConnectionAPI/DBConnectionAPI/Controllers/ConnectionsController.cs`; `DBConnectionAPI/DBConnectionAPI/Controllers/AdminController.cs` |

### SEC-API-002 Caller identity must be non-blank

| Field | Value |
| --- | --- |
| **Statement** | The caller's `User.Identity.Name` must be non-blank; a `DOMAIN\` prefix is removed before the authorization call |
| **Trigger** | Evaluation of `SecurityApiAuthorize` |
| **Enforcement** | Package security handler † (not visible in source) |
| **Applies to** | All endpoints (see [Endpoints](endpoints.md)) |
| **Outcome** | Denied; status not stated** |
| **Source** | Package documentation for `SAIF.NetCore.ServiceExtensions` † |

## Security findings

| ID | Severity | Finding | Where |
| --- | --- | --- | --- |
| SEC-01 | CRITICAL (by design) | The three retrieval endpoints return complete connection strings containing credentials in the response body | [`ConnectionsController`](endpoints/connections.md) |
| SEC-02 | CRITICAL | The three Admin endpoints return `credentials`, `user`, plaintext `pw` and the composed connection string, with no probe, no cache and no audit log ([BR-DBC-023](business-rules.md#br-dbc-023-admin-inspection-discloses-raw-credentials)) | [`AdminController`](endpoints/admin.md) |
| SEC-03 | HIGH | The Admin endpoints share the resource `DBConnAPIRetrieveResource` with the retrieval endpoints: there is no separate administrative requirement and no data-level authorization | Both controllers |
| SEC-04 | HIGH | Error messages expose the cache key (server, instance, user), the secure-setting key name, the Environment API track and, for network and generic failures, the raw provider message ([BR-DBC-016](business-rules.md#br-dbc-016-other-final-failures-map-to-500)) | `ConnectionManager` |
| SEC-05 | HIGH | Swagger JSON and UI are active in every environment and registered before authentication runs* | [Hosting pipeline](hosting-pipeline.md#api-documentation-surface) |
| SEC-06 | HIGH | The checked-in `web.config` points at a Visual Studio launcher and sets the Development environment and detailed errors; whether publishing transforms it is not visible in source** | `DBConnectionAPI/DBConnectionAPI/web.config` |
| SEC-07 | MEDIUM | Input values flow unvalidated into cache keys, secure-setting key names and templates | `ConnectionManager` |
| SEC-08 | MEDIUM | Admin credential disclosures are not audit-logged locally, while retrieval requests are ([BR-DBC-022](business-rules.md#br-dbc-022-retrieval-requests-are-audit-logged)) | `AdminController` |

The full prioritized list is on [Tech debt](tech-debt.md).

## Notes
- Authentication and the authorization handler are contributed by `SAIF.NetCore.ServiceExtensions` and are not visible in source; statements about them are package-derived (`†`) or unconfirmed (`**`).
- Policies: none are defined, so there are no unused policies to report.

## Related documentation
- [API index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Hosting pipeline](hosting-pipeline.md)
- [Endpoints](endpoints.md)
- [Dependencies](dependencies.md)
- [Configuration](configuration.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Data model](data-model.md)
- [Operational runbook](operational-runbook.md)
- [Tech debt](tech-debt.md)

> **Note:** Statements marked with `†` are derived from dependency library
> documentation via the Legends CLI. Statements marked with `*` were inferred
> from code structure or contextual evidence. Statements marked with `**` could
> not be confirmed; treat as unknown until verified.

## Sources
- DBConnectionAPI/DBConnectionAPI/Controllers/ConnectionsController.cs
- DBConnectionAPI/DBConnectionAPI/Controllers/AdminController.cs
- DBConnectionAPI/DBConnectionAPI/Startup.cs
- DBConnectionAPI/DBConnectionAPI/Services/ConnectionManager.cs
- DBConnectionAPI/DBConnectionAPI/web.config
- Pipelines/build-vars.yml
